/*
 * Simple Test program for libtcc
 *
 * libtcc can be useful to use tcc as a "backend" for a code generator.
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "../tcc-0.9.26/libtcc.h"
#pragma pack(1)
struct Bag
{
	int solt_count;
	int item_count;
	int money;
};
struct Object
{
public:
	void print(const char* msg)
	{
		printf(msg);
	}
	char n[10];
	int hp;
	char a[10];
	int mp;
	char m[10];
	int pp;
	char e[10];
	int levl;
	Bag bag;
};
#pragma pack()

/* this function is called by the generated code */
int __stdcall add(int a, int b)
{
    return a + b;
}
int main(int argc, char **argv)
{
    TCCState *s;
/*    int (*func)(int);*/

    s = tcc_new();
    if (!s) {
        fprintf(stderr, "Could not create tcc state\n");
        exit(1);
    }

    /* if tcclib.h and libtcc1.a are not installed, where can we find them */
	tcc_add_include_path(s, "C:/Users/Administrator.PC201305111017/Desktop/tcc/include/winapi");
	tcc_add_include_path(s, "C:/Users/Administrator.PC201305111017/Desktop/tcc/include");

	tcc_add_library_path(s, "C:/Users/Administrator.PC201305111017/Desktop/tcc/lib");

    /* MUST BE CALLED before any compilation */
    tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
	tcc_set_options(s, "-nostdlib");
	tcc_import_library(s, "msvcrt.dll");
//	tcc_import_library(s, "user32.dll");
	tcc_import_library(s, "kernel32.dll");
	tcc_import_library(s, "gdi32.dll");

	tcc_add_file(s, "ref.c");
//	tcc_add_file(s, "script_2.c");
//	tcc_add_library(s, "mhook");
    
    /* as a test, we add a symbol that the compiled program can use.
       You may also open a dll with tcc_add_dll() and use symbols from that */
//	tcc_add_symbol(s, "printf", &printf);
	printf("0x%08X\n", &add);
	printf("0x%08X\n", &Object::print);
//	tcc_add_symbol(s, "add", &add);

	Object hero = {0};
	memcpy(&hero.n, "hero", 4);
	hero.hp = 1;
	hero.mp = 2;
	hero.pp = 3;
	hero.levl = 4;

	hero.bag.solt_count = 20;
	hero.bag.item_count = 10;
	hero.bag.money = 99999999;

	tcc_add_symbol(s, "hero", &hero);

//	int i = tcc_run(s, 0, NULL);
     /* relocate the code */
     if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0)
		 return 1;

	 int* number = (int*)tcc_get_symbol(s, "number");
	 void* shit = tcc_get_symbol(s, "shit");
	 int (*prog_main)();
	 prog_main = (int(*)())tcc_get_symbol(s, "function");
	 if (NULL != prog_main)
	 {
		  for (int i = 0; i < 1; i++)
		  {
			  int ret = (*prog_main)();
		  }
	 }

//     /* get entry symbol */
//     func = (int (*)(int))tcc_get_symbol(s, "foo");
//     if (!func)
//         return 1;
// 
//     /* run the code */
//     func(32);

    /* delete the state */
    tcc_delete(s);

    return 0;
}
